package com.zhiyou100.review.day020.homework;

import cn.hutool.core.util.RandomUtil;

/**
 * @packageName: Homework03
 * @className: com.zhiyou100.review.day020.homework
 * @Description: TODO 死锁的两种方式
 * @author: yang
 * @date: 7/1/20
 */
public class Homework03 {
    public static void main(String[] args) {
//        Deadlock01 deadlock01 = new Deadlock01();
//        Deadlock01 deadlock02 = new Deadlock01();
//        // 创建实现接口的实现类
//
//        Thread t1 = new Thread(deadlock01, "线程 1");
//        Thread t2 = new Thread(deadlock02, "线程 2");
//        // 创建线程
//        deadlock01.thread = t2;
//        deadlock02.thread = t1;
//        // 给 实现类 的 thread 赋值，记录要等待的线程对象
//
//        t1.start();
//        t2.start();
//        // 开启线程

        Object a = new Object();
        Object b = new Object();
        // 创建锁对象

        Deadlock02 deadlock021 = new Deadlock02(a, b);
        Deadlock02 deadlock022 = new Deadlock02(b,a);

        new Thread(deadlock021,"线程 1").start();
        new Thread(deadlock022,"线程 2222").start();


    }
}

class Deadlock02 implements Runnable {

    /**
     * 外锁 和 内锁
     */
    Object internalLock;
    Object externalLock;

    public Deadlock02(Object internalLock, Object externalLock) {
        this.internalLock = internalLock;
        this.externalLock = externalLock;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (externalLock) {
                System.out.println(Thread.currentThread().getName() + " 拿到其外锁 " + externalLock);
                synchronized (internalLock) {
                    System.out.println(Thread.currentThread().getName() + " 拿到其内锁 " + internalLock);
                }
                System.out.println(Thread.currentThread().getName() + " 放手其内锁 " + internalLock);
            }
            System.out.println(Thread.currentThread().getName() + " 放手其外锁 " + externalLock);
        }
    }
}

class Deadlock01 implements Runnable {
    /**
     * 定义一个 Thread 类型的引用，记录引用
     */
    Thread thread;

    @Override
    public void run() {
        int max = 50;
        for (int i = 0; i < max; i++) {
            int n = RandomUtil.randomInt(0, 11);
            // 获取 0 到 10 的随机数
            System.out.println(Thread.currentThread().getName() + " 打印 " + n);
            try {
                Thread.sleep(200);
                // 休眠 200 ms
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (n == 5) {
                try {
                    thread.join();
                    // 调用 thread 的 join 方法，等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}
